perm filename PUPBGF.FAI[S,HE] blob sn#721899 filedate 1983-08-03 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002		TITLE	PUPFAI - Subroutines for using PUP from SAIL
C00012 ENDMK
C⊗;
	TITLE	PUPFAI - Subroutines for using PUP from SAIL

	ENTRY	PUPINIT,PUPOUT,PUPFLUSH,PUPIN,PUPFINI,PUPSTAT,PUPOBLK

;EXTERNAL INTEGER PROCEDURE PUPINIT(INTEGER CHAN,HOST,SOCKET; REFERENCE INTEGER
;					NWORDS);
;	PUPINIT opens a full-duplex BSP connection using channel CHAN
;	  (you should get CHAN using GETCHAN).  Take HOST and SOCKET
;	  from a call to NAMELOOKUP, for example.  NWORDS will tell you the
;	  maximum number of 16-bit words to put in a buffer.
;******** NOTICE that PUPOUT and PUPFLUSH are lower level than usual
;EXTERNAL INTEGER PROCEDURE PUPOUT(INTEGER WORD);
;	PUPOUT puts one word in the buffer.  It doesn't check to make sure
;	  you aren't putting in too many.
;EXTERNAL INTEGER PROCEDURE PUPFLUSH;
;	PUPFLUSH outputs any pending output to the connection.
;EXTERNAL INTEGER PROCEDURE PUPOBLK(REFERENCE INTEGER BUF; INTEGER LENGTH);
;	PUPOBLK outputs a whole buffer with LENGTH 16-bit words starting at BUF.
;	  Each word in the buffer has two 16-bit words in it, packed into the
;	  left (the buffer is just transferred into a system buffer).  Note
;	  that because of the way Whitney works, one 16-bit word goes into
;	  the buffer with the least signficant byte FIRST.
;EXTERNAL INTEGER PROCEDURE PUPIN(REFERENCE INTEGER WORD);
;	PUPIN gets one word from the connection.
;EXTERNAL INTEGER PROCEDURE PUPFINI;
;	PUPFINI closes the connection.
;EXTERNAL INTEGER PROCEDURE PUPSTAT;
;	PUPSTAT returns the status word from the last MTAPE operation on
;	  the connection [for more thorough error recovery].
; All procedures return a value indicating the outcome of the operation:
;	0 = success
;	1 = illegal channel number
;	2 = OPEN failed on device PUP
;	3 = MTAPE to establish connection failed
;	4 = OUT failed while outputting buffer
;	5 = IN failed while reading buffer
;	6 = packet had an odd number of bytes in it on input
;	7 = buffer in block-mode output was too long to fit in buffer

;I don't believe this one
OPDEF ADJBP [IBP]

;AC defs
P←←17

;Defs for PUP MTAPE
MFUNC←←0
MSTAT←←1
MLSOCK←←2
MWAIT←←3
MBYTE←←4
MFSOCK←←5
MFHOST←←6

;Data area
RETAD:	BLOCK	1	; Return address
WRDAD:	BLOCK	1	; Address for no. of words in buffer, or word to return
MTPBLK:	BLOCK	7	; block for PUP MTAPE functions
CHANWD:	BLOCK	1	; channel in correct place for UUOs
OPNBLK:	0		; block for PUP OPEN function
	SIXBIT/PUP/
	OBUFH,,IBUFH
OBUFH: BLOCK 3 ↔ IBUFH: BLOCK 3 ;buffer headers...don't separate these

PUPINIT: POP	P,RETAD
	POP	P,WRDAD
	POP	P,MTPBLK+MFSOCK
	POP	P,MTPBLK+MFHOST
; Now get channel and set it up for future UUOs
	MOVEI	1,1	; Illegal channel
	POP	P,2
	CAILE	2,17
	 JRST	@RETAD	; Illegal channel error
	LSH	2,=18+5
	MOVEM	2,CHANWD
; Establish connection with foreign host
;  zero buffer headers
	SETZM	OBUFH
	MOVE	2,[OBUFH,,OBUFH+1]
	BLT	2,IBUFH+2
;  open device PUP
	MOVEI	1,2	; OPEN failed
	MOVE	2,[OPEN 0,OPNBLK]
	IOR	2,CHANWD
	XCT	2
	 JRST	@RETAD	; OPEN failed error
;  set byte size to 8
	MOVEI	2,=8
	DPB	2,[POINT 6,OBUFH+1,11]
	DPB	2,[POINT 6,IBUFH+1,11]
;  use MTAPE to establish connection
	SETZM	MTPBLK+MFUNC	; function = establish connection
	SETZM	MTPBLK+MSTAT	; status = no error yet
	SETOM	MTPBLK+MLSOCK	; local socket = generate one (-1)
	SETOM	MTPBLK+MWAIT	; wait for function completion
	MOVEM	2,MTPBLK+MBYTE	; byte size = 8
	MOVE	2,[MTAPE 0,MTPBLK]
	IOR	2,CHANWD
	XCT	2
	MOVEI	1,3	; MTAPE failed
	MOVE	2,MTPBLK+MSTAT
	ANDI	2,77
	JUMPN	2,@RETAD	; MTAPE failed error
;  set up buffers with OUT UUO.
	MOVEI	1,4	; OUT failed
	MOVE	2,[OUT 0,]
	IOR	2,CHANWD
	XCT	2
	JRST	.+2
	JRST	@RETAD	; OUT UUO failed error
;  set the number of 16-bit words in the buffer
	MOVE	2,OBUFH+2
	LSH	2,-1	; bytes to 16-bit words
	MOVEM	2,@WRDAD
;  successful operation
	MOVEI	1,0	; success
	JRST	@RETAD

PUPSTAT: MOVE	1,MTPBLK+MSTAT
	POPJ	P,

PUPOUT:	POP	P,RETAD
	POP	P,2
	MOVE	3,2
	LSH	3,-=8
	IDPB	2,OBUFH+1	; Deposit low-order byte
	IDPB	3,OBUFH+1	; Deposit high-order byte
	SOS	OBUFH+2		; Update count just in case
	SOS	OBUFH+2
	MOVEI	1,0		; and give success return
	JRST	@RETAD

PUPFLUSH: MOVE	2,[OUT 0,]
	MOVEI	1,0
	IOR	2,CHANWD
	XCT	2
	POPJ	P,		; success return
	MOVEI	1,4		; OUT failed
	POPJ	P,		; OUT failed error

PUPOBLK:POP	P,RETAD
	POP	P,3		; get length in 16-bit words
	POP	P,2		; and address of user buf
	MOVEI	1,7		; buffer too long
	MOVE	4,3		; get length in 8-bit bytes
	LSH	4,1
	ADDI	3,1		; get length in 36-bit words (rounded up)
	LSH	3,-1
	CAMLE	4,OBUFH+2
	 JRST	@RETAD		; buffer too long error
	MOVE	5,OBUFH+2	; fix length in system buf header
	SUB	5,4
	MOVEM	5,OBUFH+2
	IBP	OBUFH+1		; move byte pointer to first byte in system buf
	HRL	5,2		; set up BLT pointer:
	HRR	5,OBUFH+1	;  5 = user buf start,,system buf start
	HRR	6,OBUFH+1
	ADDI	6,-1(3)		;  6 = system buf end
	IOR	6,[BLT 5,0]	;  6 = BLT instruction
	XCT	6
	SUBI	4,1		; now fix up the byte pointer in system buf
	ADJBP	4,OBUFH+1
	MOVEM	4,OBUFH+1
	MOVE	4,[OUT 0,]	; do OUT instruction to output buffer
	MOVEI	1,0		; success return
	IOR	4,CHANWD
	XCT	4
	JRST	@RETAD
	MOVEI	1,4		; OUT failed
	JRST	@RETAD		; OUT failed error

PUPIN:	POP	P,RETAD
	POP	P,WRDAD
;  try to get one word from buffer
PUPI2:	MOVEI	1,6		; odd no. of bytes
	SOSGE	IBUFH+2
	 JRST	GETBUF
	SOSGE	IBUFH+2
	 JRST	@RETAD		; odd bytes error
	ILDB	3,IBUFH+1	; and low-order byte
	ILDB	2,IBUFH+1	; get high-order byte
	LSH	2,=8		; assemble word
	IOR	2,3
	MOVEM	2,@WRDAD	; store it
	MOVEI	1,0		; success return
	JRST	@RETAD
;  none left in buffer - read a buffer
GETBUF:	MOVE	2,[IN 0,]
	IOR	2,CHANWD
	XCT	2
	JRST	PUPI2
	MOVEI	1,5		; IN failed
	JRST	@RETAD		; IN failed error

PUPFINI: MOVE	2,[CLOSE 0,]
	IOR	2,CHANWD
	XCT	2
;  do the RELEASE from SAIL now
;	MOVE	2,[RELEAS 0,]
;	IOR	2,CHANWD
;	XCT	2
	MOVEI	1,0		; success return
	POPJ	P,

	END